package belf.migrate.engine.job;

import belf.migrate.api.job.JobCode;
import belf.migrate.api.type.ResultDataType;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import java.util.ArrayList;
import java.util.List;

/**
 * 一个Job执行完的结果。封装数据库操作的执行结果
 */
public class JobResult {

    /** item类型名称 */
    private String typeName;
    /** 执行结果代码，参考{@link JobCode} */
    private int code;
    /** 执行Job后的提示信息 */
    private String message;

    /** 子任务完成数量 */
    private int completes = 0;
    /** 子任务失败数量 */
    private int failtures = 0;

    /** 子任务总数量 */
    private int total = 0;
    /** 子任务成功情况 */
    private List<JobResultItem> successItems = new ArrayList<>();

    /** 子任务失败情况 */
    private List<JobResultItem> failureItems = new ArrayList<>();

    /** 执行Job的ID */
    private Long jobId;

    /** 执行Job的返回数据类型 */
    private String dataType = ResultDataType.RESULT.getType();

    private String errors;

    private Object data;

    /** job执行的开始时间 */
    private String startTime;
    /** job执行的结束时间。对于STREAM类型的任务，没有结束时间 */
    private String endTime;

    private String timeConsuming;

    /** 成功率 */
    private String successRate = "100%";

    private Integer errorTipsCount = 0;

    public JobResult(int code, String message) {
        this.code = code;
        this.message = message;
    }

    public JobResult(int code, String message, List<JobResultItem> successItems, List<JobResultItem> failtureItems) {
        this.code = code;
        this.message = message;
        this.successItems = successItems;

        completes += successItems.size();
        failtures += failtureItems.size();
    }

    public JobResult(int code, String message, String errors) {
        this.code = code;
        this.message = message;
        this.errors = errors;
    }

    public JobResult(Long jobId, String dataType, Object data, int code) {
        this.jobId = jobId;
        this.dataType = dataType;
        this.data = data;
        this.code = code;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public String getErrors() {
        return errors;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public int getCompletes() {
        return completes;
    }

    public int getFailtures() {
        return failtures;
    }

    public List<JobResultItem> getSuccessItems() {
        return successItems;
    }

    public List<JobResultItem> getFailureItems() {
        return failureItems;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public Long getJobId() {
        return jobId;
    }

    public void setJobId(Long jobId) {
        this.jobId = jobId;
    }

    public String getDataType() {
        return dataType;
    }

    public void setDataType(String dataType) {
        this.dataType = dataType;
    }

    public String getStartTime() {
        return startTime;
    }

    public void setStartTime(String startTime) {
        this.startTime = startTime;
    }

    public String getEndTime() {
        return endTime;
    }

    public void setEndTime(String endTime) {
        this.endTime = endTime;
    }

    public String getTimeConsuming() {
        return timeConsuming;
    }

    public void setTimeConsuming(String timeConsuming) {
        this.timeConsuming = timeConsuming;
    }

    public String getTypeName() {
        return typeName;
    }

    public void setTypeName(String typeName) {
        this.typeName = typeName;
    }

    public String getSuccessRate() {
        return successRate;
    }

    public void setSuccessRate(String successRate) {
        this.successRate = successRate;
    }

    public Integer getErrorTipsCount() {
        return errorTipsCount;
    }

    public void setErrorTipsCount(Integer errorTipsCount) {
        this.errorTipsCount = errorTipsCount;
    }

    public int getTotal() {
        return total;
    }

    public void setTotal(int total) {
        this.total = total;
    }

    public void addTipsCount() {
        errorTipsCount++;
    }

    public void addItem(JobResultItem item) {
        if (item.getCode() == JobCode.SUCCESS) {
            successItems.add(item);
            completes++;
        } else {
            failureItems.add(item);
            failtures++;
            if (item.getErrorTips() != null) {
                addTipsCount();
            }
        }
        successRate = (completes + failtures) == 0 ? "100%" : String.format("%.2f", (double) completes / (completes + failtures) * 100) + "%";
        total++;
    }

    @Override
    public String toString() {
        return "JobResult{" +
                "code=" + code +
                ", message='" + message + '\'' +
                ", completes=" + completes +
                ", failtures=" + failtures +
                ", successItems=" + successItems +
                ", failureItems=" + failureItems +
                ", errors='" + errors + '\'' +
                '}';
    }

    public JsonObject toJson() {
        Gson gson = new Gson();
        String jsonString = gson.toJson(this);
        // 将 JSON 字符串解析为 JsonObject
        JsonObject jsonObject = JsonParser.parseString(jsonString).getAsJsonObject();
        return jsonObject;
    }
}
